package com.cdfahe.common.util.mail;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

/**
 * 邮件相关工具类
 * @author  Karl
 * @version 
 * @since   JDK1.6
 */
public class MailSender {
	
	public static String TEXT = "text/plain;charset=utf-8";
    public static String HTML = "text/html;charset=utf-8";
    public static final String MAIL_PATH = "config/webconf.xml";
    
	private String username = "";

	private String password = "";
	
	
	
	private static String  GOOGLESSL_SERVERS = "smtp.gmail.com";
	private static String  GOOGLESSL_PORT ="465";
	private static String  GOOGLESSL_USERNAME ="cdfahe@gmail.com";
	private static String  GOOGLESSL_PASSWORD ="l172733456";
	
	
	private static String  STARTSSL_SERVERS = "smtp.qq.com";
	private static String  STARTSSL_PORT ="465";
	private static String  STARTSSL_USERNAME ="172733456@qq.com";
	private static String  STARTSSL_PASSWORD ="123456";
	
	private static String[] SSLs = new String[]{"成都法和药业有限责任公司","STARTSSL","GEOTRUST"};
	

	public MailSender() {

	}
	
	/**
	 * 发送用户名密码给用户
	 * @param username 用户名
	 * @param password 密码
	 * @param email 邮箱;
	 * @param url 访问地址
	 * @return 
	 */
	public boolean sendUsernameAndPasswordToUser(String username, String password, String email, String url) {
		MailUtils.setConfigFile(MAIL_PATH);
		Hashtable<String, String> parm = new Hashtable<String, String>();
		parm.put("username", username);
		parm.put("password", password);
		parm.put("url", url);
		parm.put("TO", email);
		try {
			Mail mail = MailUtils.getMailForUserPassWord("toUser", parm);
			return sendMail(mail, true);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 发送用户请求的找回密码邮件
	 * @param updatepwdid 更新码
	 * @param email 邮箱;
	 * @return 
	 */
	public boolean sendResetPwdMail(String updatepwdid,String finalurl, String email) {
		MailUtils.setConfigFile(MAIL_PATH);
		Hashtable<String, String> parm = new Hashtable<String, String>();
		parm.put("updatepwdid", updatepwdid);
		parm.put("finalurl", finalurl);
		parm.put("TO", email);
		try {
			Mail mail = MailUtils.getMailForUserPassWord("resetPwd", parm);
			return sendMail(mail, true);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 发送测试项目跟进通知邮件
	 * @param email 邮箱;
	 * @return 
	 */
	public boolean sendTestPrj(String email, String projectid, String url) {
		MailUtils.setConfigFile(MAIL_PATH);
		Hashtable<String, String> parm = new Hashtable<String, String>();
		parm.put("TO", email);
		parm.put("projectid", projectid);
		parm.put("url", url);
		try {
			Mail mail = MailUtils.getMail("testPrj", parm);
			return sendMail(mail, true);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	public static String readFileByLines(String fileName) {
			StringBuffer s =new StringBuffer();
			File file = new File(fileName);
			BufferedReader reader = null;
			try {
	//			System.out.println("以行为单位读取文件内容，一次读一整行：");
				reader = new BufferedReader(new FileReader(file));
				String tempString = null;
				int line = 1;
				// 一次读入一行，直到读入null为文件结束
				while ((tempString = reader.readLine()) != null) {
					// 显示行号
	//				System.out.println("line " + line + ": " + tempString);
					s.append(tempString);
					line++;
				}
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (reader != null) {
					try {
						reader.close();
					} catch (IOException e1) {
					}
				}
			}
			return s.toString();
		}

	public static void getMailCase(String server, String port, String user,
			String pwd, String ssl) {
		MailSender mt = new MailSender();
		Mail mail = new Mail(server, user, pwd, user);
		mail.setPort(port);
		mail.setFromname(ssl);
		// mail.addReplyto("roy_xiao.com");
		mail.addTo("donzell88@qq.com");
		mail.addBcc("donzell88@qq.com");
		mail.setSubject("这里是主题的内容");
		mail.setContent("这里是药品的广告啊，什么的等等等的信息内容！");
//		mail.setContent(readFileByLines("E://1.htm"));
		mail.setContent(readFileByLines("E://2.zip"));
		System.setProperty("javax.net.debug", "ssl"); 
		
		
		
		mail.setUseSSL(true);
		
		if (mt.sendMail(mail,false)) {
			System.out.println("send mail successful");
		} else {
			System.out.println("send mail failure");
		}

	}

	public static void main(String args[]) throws Exception {
		//测试用例1
		getMailCase(GOOGLESSL_SERVERS,GOOGLESSL_PORT,GOOGLESSL_USERNAME,GOOGLESSL_PASSWORD,SSLs[0]);
//		getMailCase(STARTSSL_SERVERS,STARTSSL_PORT,STARTSSL_USERNAME,STARTSSL_PASSWORD,SSLs[1]);
//		getMailCase(GEOTRUST_SERVERS,GEOTRUST_PORT,GEOTRUST_USERNAME,GEOTRUST_PASSWORD,SSLs[2]);
		
		//测试用例2
		/*MailTools mt = new MailTools();
		String host="smtp.qq.com";
		String sender = "172733456@qq.com";
		String senderpass = "123456";
		String reserver = "172733456@qq.com";
		Mail mail = new Mail(host,sender,senderpass,reserver);
//		 Mail mail = new Mail("smtp.gmail.com", "john_zhu@i-len.org",
//		 "308E65", "batxut@gmail.com");
		 mail.setPort("465");
		 mail.setFromname("Fahe");				//发件人名称
		 mail.addReplyto("donzell88@qq.com");	//点击回复时候，回复信息的地址
		 mail.addTo("cdfahe@qq.com");			//收件人
//		 mail.addTo("cdfahe@qq.com");
		 mail.addBcc("lll666555@vip.qq.com");  //也会往这个邮箱发信
		 mail.setSubject("test1");
		 mail.setContent("Test1!");
		 mail.setUseSSL(true);
		 if (mt.sendMail(mail)) {
		 System.out.println("send mail successful");
		 } else {
		 System.out.println("send mail failure");
		 }*/
		//测试用例3
		/*MailTools mt = new MailTools();
		String host="smtp.qq.com";
		String sender = "172733456@qq.com";
		String senderpass = "123456";
		String reserver = "172733456@qq.com";
		Mail mail = new Mail(host,sender,senderpass,reserver);
//		 Mail mail = new Mail("smtp.gmail.com", "john_zhu@i-len.org",
//		 "308E65", "batxut@gmail.com");
		 mail.setPort("465");
		 mail.setFromname("成都法和药业");				//发件人名称
		 mail.addReplyto("donzell88@qq.com");	//点击回复时候，回复信息的地址
		 mail.addTo("cdfahe@qq.com");			//收件人
//		 mail.addTo("cdfahe@qq.com");
		 mail.addBcc("lll666555@vip.qq.com");  //也会往这个邮箱发信
//		mail.setAttached(true);
//		mail.addAttached(
//				"0.xml",
//				"file:/e://0.xml");
//		mail.addAttached(
//				"01109042700.key",
//				"file:/data/cheney/programming/workspace/ProductDownload/LicenseFolder/09/04/27/01109042700.key");
		mail.setSubject("Product Download");
		mail.setContent("Product download.");
		mt.sendMail(mail);*/
	}

	private class Authenticator extends javax.mail.Authenticator {
		public PasswordAuthentication getPasswordAuthentication() {
			return new PasswordAuthentication(username, password);
		}
	}

	public boolean sendMail(Mail mail,boolean isHTML) {
		username = mail.getUsername();
		password = mail.getPassword();
		boolean flag = true;
		// Get system properties
		Properties props = System.getProperties();
		if (mail.isUseSSL()) {
			setPropertiesWithSSL(props, mail);
		} else {
			setPropertiesWithoutSSL(props, mail);
		}
		// props.put("mail.debug", "true");
		// Get session
		Authenticator auth = new Authenticator();
		Session session = Session.getDefaultInstance(props, auth);

		// Define message
		MimeMessage message = new MimeMessage(session);
		try {
			String fromname = mail.getFromname();
			if (fromname != null && !fromname.equals("")) {
				message.setFrom(new InternetAddress(mail.getFrom(), fromname));
			} else {
				message.setFrom(new InternetAddress(mail.getFrom()));
			}

			// set to reply
			List<String> replyToList = mail.getReplyto();
			if (replyToList != null && replyToList.size() != 0) {
				Address[] replyArray = new InternetAddress[replyToList.size()];
				Iterator<String> replyIt = replyToList.iterator();
				int count = 0;
				while (replyIt.hasNext()) {
					String reply = replyIt.next();
					replyArray[count] = new InternetAddress(reply);
					count++;
				}
				message.setReplyTo(replyArray);
			}

			// Set to cc address
			List<String> toList = mail.getTo();
			if (toList != null && toList.size() != 0) {
				Iterator<String> it = toList.iterator();
				while (it.hasNext()) {
					String to = it.next();
					// System.out.println("cc:" + cc);
					message.addRecipient(Message.RecipientType.TO,
							new InternetAddress(to));
				}
			}

			// Set to cc address
			List<String> ccList = mail.getCc();
			if (ccList != null && ccList.size() != 0) {
				Iterator<String> it = ccList.iterator();
				while (it.hasNext()) {
					String cc = it.next();
					// System.out.println("cc:" + cc);
					message.addRecipient(Message.RecipientType.CC,
							new InternetAddress(cc));
				}
			}

			// Set to bcc address
			List<String> bccList = mail.getBcc();
			if (bccList != null && bccList.size() != 0) {
				Iterator<String> it = bccList.iterator();
				while (it.hasNext()) {
					String bcc = it.next();
					// System.out.println("bcc:" + bcc);
					message.addRecipient(Message.RecipientType.BCC,
							new InternetAddress(bcc));
				}
			}

			message.setSubject(MimeUtility.encodeText(mail.getSubject(), "UTF-8", "B"));

			// send mail with attached
			if (mail.isAttached()) {
				Multipart multiPart = new MimeMultipart("mixed");
				message.setContent(multiPart);
				// add the attached
				Map<String, String> attachedMap = mail.getAttached();
				Iterator<String> iterator = attachedMap.keySet().iterator();
				while (iterator.hasNext()) {
					String key = iterator.next();
					String value = attachedMap.get(key);
					MimeBodyPart attached = new MimeBodyPart();
					DataSource dataSource = new FileDataSource(new File(
							new URI(value)));
					DataHandler handler = new DataHandler(dataSource);
					attached.setDataHandler(handler);
					attached.setFileName(MimeUtility.encodeText(key));
					multiPart.addBodyPart(attached);
				}
				MimeBodyPart content = new MimeBodyPart();
				multiPart.addBodyPart(content);

				Multipart contentMultiPart = new MimeMultipart("related");
				content.setContent(contentMultiPart);
				MimeBodyPart textContent = new MimeBodyPart();
				//如果是HTML格式，则使用HTML格式发送
				if(isHTML){
					textContent.setDataHandler(new DataHandler(mail.getContent(), HTML));
				}else{
					textContent.setText(mail.getContent(), "UTF8");
				}
				contentMultiPart.addBodyPart(textContent);
				message.saveChanges();
			} else {
				// create the message part
				MimeBodyPart messageBodyPart = new MimeBodyPart();
				//如果是HTML格式，则使用HTML格式发送
				if(isHTML){
					messageBodyPart.setDataHandler(new DataHandler(mail.getContent(), HTML));
				}else{
					messageBodyPart.setText(mail.getContent(), "UTF8");
				}

				Multipart multipart = new MimeMultipart();
				multipart.addBodyPart(messageBodyPart);

				// Put parts in message
				message.setContent(multipart);

				message.saveChanges();
			}
			// Send the message
			Transport.send(message);
		} catch (Exception e) {
			e.printStackTrace();
			flag = false;
		}
		return flag;
	}
	
	public boolean sendMail(Mail mail) {
		username = mail.getUsername();
		password = mail.getPassword();
		boolean flag = true;
		// Get system properties
		Properties props = System.getProperties();
		if (mail.isUseSSL()) {
			setPropertiesWithSSL(props, mail);
		} else {
			setPropertiesWithoutSSL(props, mail);
		}
		// props.put("mail.debug", "true");
		// Get session
		Authenticator auth = new Authenticator();
		Session session = Session.getDefaultInstance(props, auth);

		// Define message
		MimeMessage message = new MimeMessage(session);
		try {
			String fromname = mail.getFromname();
			if (fromname != null && !fromname.equals("")) {
				message.setFrom(new InternetAddress(mail.getFrom(), fromname));
			} else {
				message.setFrom(new InternetAddress(mail.getFrom()));
			}

			// set to reply
			List<String> replyToList = mail.getReplyto();
			if (replyToList != null && replyToList.size() != 0) {
				Address[] replyArray = new InternetAddress[replyToList.size()];
				Iterator<String> replyIt = replyToList.iterator();
				int count = 0;
				while (replyIt.hasNext()) {
					String reply = replyIt.next();
					replyArray[count] = new InternetAddress(reply);
					count++;
				}
				message.setReplyTo(replyArray);
			}

			// Set to cc address
			List<String> toList = mail.getTo();
			if (toList != null && toList.size() != 0) {
				Iterator<String> it = toList.iterator();
				while (it.hasNext()) {
					String to = it.next();
					// System.out.println("cc:" + cc);
					message.addRecipient(Message.RecipientType.TO,
							new InternetAddress(to));
				}
			}

			// Set to cc address
			List<String> ccList = mail.getCc();
			if (ccList != null && ccList.size() != 0) {
				Iterator<String> it = ccList.iterator();
				while (it.hasNext()) {
					String cc = it.next();
					// System.out.println("cc:" + cc);
					message.addRecipient(Message.RecipientType.CC,
							new InternetAddress(cc));
				}
			}

			// Set to bcc address
			List<String> bccList = mail.getBcc();
			if (bccList != null && bccList.size() != 0) {
				Iterator<String> it = bccList.iterator();
				while (it.hasNext()) {
					String bcc = it.next();
					// System.out.println("bcc:" + bcc);
					message.addRecipient(Message.RecipientType.BCC,
							new InternetAddress(bcc));
				}
			}

			message.setSubject(MimeUtility.encodeText(mail.getSubject(), "UTF-8", "B"));

			// send mail with attached
			if (mail.isAttached()) {
				Multipart multiPart = new MimeMultipart("mixed");
				message.setContent(multiPart);
				// add the attached
				Map<String, String> attachedMap = mail.getAttached();
				Iterator<String> iterator = attachedMap.keySet().iterator();
				while (iterator.hasNext()) {
					String key = iterator.next();
					String value = attachedMap.get(key);
					MimeBodyPart attached = new MimeBodyPart();
					DataSource dataSource = new FileDataSource(new File(
							new URI(value)));
					DataHandler handler = new DataHandler(dataSource);
					attached.setDataHandler(handler);
					attached.setFileName(MimeUtility.encodeText(key));
					multiPart.addBodyPart(attached);
				}

				MimeBodyPart content = new MimeBodyPart();
				multiPart.addBodyPart(content);

				Multipart contentMultiPart = new MimeMultipart("related");
				content.setContent(contentMultiPart);
				MimeBodyPart textContent = new MimeBodyPart();
				contentMultiPart.addBodyPart(textContent);
				textContent.setText(mail.getContent(), "UTF8");

				message.saveChanges();
			} else {
				// create the message part
				MimeBodyPart messageBodyPart = new MimeBodyPart();

				// fill message
				messageBodyPart.setText(mail.getContent(), "UTF8");

				Multipart multipart = new MimeMultipart();
				multipart.addBodyPart(messageBodyPart);

				// Put parts in message
				message.setContent(multipart);

				message.saveChanges();
			}
			// Send the message
			Transport.send(message);
		} catch (Exception e) {
			e.printStackTrace();
			flag = false;
		}
		return flag;
	}

	private void setPropertiesWithoutSSL(Properties props, Mail mail) {
		// Setup mail server
		props.put("mail.smtp.host", mail.getHost());
		props.put("mail.smtp.auth", "true");
	}

	private void setPropertiesWithSSL(Properties props, Mail mail) {
		final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
//		Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
		// Setup mail server
		props.put("mail.smtp.host", mail.getHost());
		props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
		props.setProperty("mail.smtp.socketFactory.fallback", "false");
		props.setProperty("mail.smtp.port", mail.getPort());
		props.setProperty("mail.smtp.socketFactory.port", mail.getPort());
//		props.setProperty("mail.smtp.startssl.enable", "true");
		props.put("mail.smtp.auth", "true");
	}
}
